#!/usr/bin/python
# -*- coding: utf-8 -*-

#This file is part of pyLot library.
#
# pyLot is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# pyLot is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with pyLot.  If not, see <http://www.gnu.org/licenses/>.

__author__ = u'Pierre Puiseux, Guillaume Baty'
__copyright__ = u"Copyright 2011-2012 (C) andheo, Université de Pau et des Pays de l'Adour"
__credits__ = [u'Pierre Puiseux', u'Guillaume Baty']
__license__ = "GNU Lesser General Public License"

__all__ = [u'BaseWidgetInterface']

from Qt4 import QtGui, QtCore

from pyLot.core import (Path, LANG)
from pyLot.interfaces import (UiInterface)

from _pylot.qtgui.tools import (set_qt_widget_texts, get_icon)
from _pylot.qtgui import install_qtranslator

class BaseWidgetInterface(UiInterface):
  u"""
  Un widget vide, avec une interface pyLot.
  
  .. warning ::
  
    Name is WidgetInterface and not WidgetInterface because class isn't
    based on QWidget.  
    
  Un widget pyLot propose au minimum 

    - un menu (:meth:`getMenu` et :meth:`menu_`)
    - une tool bar (:meth:`getToolBar`)
    - un editeur de preferences (:meth:`getPreferences`)
  
  Un widget pyLot doit nécessairement être associé à un handler qui s'occupe 
  des traitements de données.
  
  NOTE POUR DOC: parler de l'ordre d'appel des méthodes recursives 
  switchUserLevel, translate, ...
  L'ordre d'exécution est le suivant :
    appel/installation des méthodes globales (niveau pylot)
    appel des méthodes des enfants (car ceux-ci sont 100% indépendant)
    appel des méthodes des pref si dispo
    appel de la méthode locale au widget (car le widget peut dépendre de l'état
    de ses enfants)
  """

  def __init__(self, handler=None):
    u"""
    :param handler: un handler associé au widget. 
          Le widget traite de l'interface, le handler traite des données.
    :type handler: HandlerInterface (?)
           
    """
    UiInterface.__init__(self, handler)
    self.__translators = {}
    self.__current_locale = None

    self._tool_bars = []
    self._menus = []
    self._widgets = []
    self._pref = None

    self._plugin_path = Path(u'.').abspath()
    self._children = {}

  menus = property(fget=lambda self:self._menus)
  tr_ = property(fget=lambda self:self._handler.tr_)

  # ============================================================================
  # Tool-methods
  # ============================================================================

  def _setTexts(self, widget_text_list, field=u'text'):
    u"""
    Puts texts (titles, tooltips, shortcuts, ...) for a list of widgets.

    :param widget_text_list: list of couple (widget(QWidget), text(unicode))
    :type widget_text_list: obj:`list`
    :param field: type of text you want to set : tooltip, shortcut or text [default]
    :type field: obj:`unicode`
    """
    set_qt_widget_texts(widget_text_list, field)

  def _setIcons(self, widget_icon_list):
    u"""
    Finds and puts icons (from filename) for a list of widgets.

    :param widget_icon_list: list of couple (widget(QWidget), filename(unicode))
    :type widget_icon_list: obj:`list`
    """
    for widget, path in widget_icon_list :
      widget.setIcon(self._icon(path))

  def _icon (self, filename):
    u"""
    Tries to find image file "filename" from icon directories and generates a
    QIcon object from this path.
    If fails, searches in current working directory or return an empty QIcon.
    
    :param filename: picture filename
    :type filename: unicode
    :rtype: QtGui.QIcon
    """
    if isinstance(filename, QtGui.QIcon) :
      return filename
    try :
      icon = get_icon(filename, [Path(self._plugin_path, u'icons')])
    except AttributeError :
      icon = get_icon(filename)
    return icon


  def _createConnexions(self):
    u"""
    Connexions des actions/signaux aux méthodes.

    .. note ::
      You should implement this class    

    Example ::
      self.connect(self.action_quit, SIGNAL("triggered()"), exit)
    """

  def translate(self, locale=None, force=False, recursive=True):
    u"""
    Retranslates widget only if locale has changed.
    You can force it with force=True.
    
    This method calls recursivly translate method of all children's widgets and
    preferences. You can disable recursivity with recursive=False.

    If locale is not defined, uses handler locale. if handler locale is not
    defined, uses system default locale.
    
    .. warning ::
      Translation instructions must be defined in _translate method.
      Only inherits this method if you really know what you are talking about.
    """
    if locale is None :
      locale = self.handler.getCurrentLocale()
    if locale is None : #means handler has never been translated
      locale = LANG

    if locale == self.__current_locale and force is False :
      return
    self.__current_locale = locale

    # Install global QTranslator for ui files
    install_qtranslator(locale)

    # Install local QTranslator for ui files
    try :
      self._plugin_path
    except AttributeError :
      pass
    else :
      try :
        translator = self.__translators[locale]
      except KeyError :
        translator = QtCore.QTranslator()
        self.__translators[locale] = translator
      i18n_path = unicode(Path(self._plugin_path, u'i18n', u'%s.qm' % locale).abspath())
      loaded = translator.load(i18n_path)

      for old_translator in self.__translators.values():
        QtCore.QCoreApplication.instance().removeTranslator(old_translator)

      if loaded :
        QtCore.QCoreApplication.instance().installTranslator(translator)

    # translate submodules
    if recursive is True :
      for module in self._children.values() + self._widgets :
        module.translate(locale, force=force, recursive=recursive)

    # retranslate ui file if available
    try :
      self.retranslateUi(self)
    except AttributeError :
      pass

    # retranslate widget
    self._translate()

  def updateData(self):
    u"""
    Updates core data from widget fields
    """
    self._updateData()

  def refresh(self):
    u"""
    Updates widget fields from core data
    """
    for module in self._children.values() + self._widgets :
      module.refresh()

    self._refresh()

  def decorate(self):
    u"""
    Decorates widget (set icons, images, etc.).
    This method calls recursivly decorate method of all children's 
    widgets and preferences.

    .. warning ::
      Instructions must be defined in private method _decorate.
      Only inherits this method if you really know what you are talking about.
    """
    for module in self._children.values() + self._widgets :
      module.decorate()

    self._decorate()

  # ============================================================================
  # Methods to implement
  # ============================================================================

  def _translate (self) :
    pass

  def _updateData(self):
    pass

  def _refresh(self):
    pass

  def _decorate (self) :
    pass


